#include<iostream>
#include<memory>
#include<vector>
#include<fstream>
#include<sstream>
#include<stdexcept>
#include"StrBlob.h"
#include"StrBlobPtr.h"
using namespace std;
vector<int>* vector_factory();
void alloc_vector(vector<int> *v);
void alloc_vector(shared_ptr<vector<int>> pv);
void print_vector(vector<int> *v);
void print_vector(shared_ptr<vector<int>> pv);
void practice_12_6();
void practice_12_7();
void practice_12_9();
void practice_12_16();
void practice_12_20();
int main()
{
	//practice_12_6();
	//practice_12_7();
	//practice_12_9();
	//practice_12_16();
	practice_12_20();
	return 0;
}
StrBlob::StrBlob():data(make_shared<vector<string>>()){}
StrBlob::StrBlob(initializer_list<string> il):data(make_shared<vector<string>>(il)){}
void StrBlob::check(size_type i,const string &msg)const
{
	if(i>=data->size())
		throw out_of_range(msg);
}
string& StrBlob::front()
{
	do_front();
}
string& StrBlob::front() const
{
	do_front();
}
string& StrBlob::back()
{
	do_back();
}
string& StrBlob::back() const
{
	do_back();
}
void StrBlob::pop_back()
{
	check(0,"pop_back on empty StrBlob");
	data->pop_back();
}
vector<int>* vector_factory()
{
	return new vector<int>();
}
void alloc_vector(vector<int> *v)
{
	int num;
	while(cin>>num)
		v->push_back(num);
}
void alloc_vector(shared_ptr<vector<int>> pv)
{
	int num;
	while(cin>>num)
		pv->push_back(num);
}
void print_vector(shared_ptr<vector<int>> pv)
{
	for(auto c:*pv)
		cout<<c<<" ";
	cout<<endl;
}
void print_vector(vector<int> *v)
{
	for(auto c:*v)
		cout<<c<<" ";
	cout<<endl;
}
void practice_12_6()
{
	vector<int> *pv=vector_factory();
	alloc_vector(pv);
	print_vector(pv);
	delete(pv);
}
void practice_12_7()
{
	shared_ptr<vector<int>> pv=make_shared<vector<int>>();
	alloc_vector(pv);
	print_vector(pv);
}
void practice_12_9()
{
	int *q=new int(42),*r=new int(100);
	r=q;
}
void practice_12_16()
{
	unique_ptr<int> p1;
	unique_ptr<int> p2(new int(42));
	//p1=p2;
}
shared_ptr<vector<string>> StrBlobPtr::check(size_t i,const string &msg)const
{
	auto ret=wptr.lock();
	if(!ret)
		throw runtime_error("unbound StrBlobPtr");
	if(i>=ret->size())
		throw out_of_range(msg);
	return ret;
}
string& StrBlobPtr::deref() const
{
	auto p=check(curr,"deference past end");
	return (*p)[curr];
}
StrBlobPtr& StrBlobPtr::incr()
{
	check(curr,"increment past end of StrBlobPtr");
	++curr;
	return *this;
}
StrBlobPtr StrBlob::begin()
{
	return StrBlobPtr(*this);
}
StrBlobPtr StrBlob::end()
{
	auto ret=StrBlobPtr(*this,data->size());
	return ret;
}
void practice_12_20()
{
	ifstream input("text.txt");
	string line;
	StrBlob sb;
	while(getline(input,line)){
		istringstream iss(line);
		string word;
		while(iss>>word)
			sb.push_back(word);
	}
	for(auto it=sb.begin();it.get_curr()!=sb.end().get_curr();it.incr()){
		cout<<it.deref()<<" ";
	}
}